package be.kuleuven.cs.mop.gui.components;


import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.swing.JPanel;

import be.kuleuven.cs.mop.domain.exceptions.TaskManagerException;
import be.kuleuven.cs.mop.domain.model.Task;
import be.kuleuven.cs.mop.domain.model.TaskType;
import be.kuleuven.cs.mop.domain.model.impl.Field;
import be.kuleuven.cs.mop.domain.model.impl.FieldType;
import be.kuleuven.cs.mop.gui.util.SwingUtils;



/**
 * Custom {@link JPanel} for {@link TaskType} field input
 */
public class TaskFieldsInput extends JPanel {
	private static final long serialVersionUID = 1L;
	
	private SortedMap<String, TextInput>	fields	=
		new TreeMap<String, TextInput>();
	private TaskType						type;
	
	
	public TaskFieldsInput(final Task task) {
		this(task.getType());
		
		for (final Entry<String, Field> entry : task.getFields().entrySet()) {
			final Object value = entry.getValue().getValue();
			fields.get(entry.getKey()).setText(
					((value == null) ? "" : value.toString()));
		}
	}
	public TaskFieldsInput(final TaskType type) {
		super(new GridBagLayout());
		setType(type);
		
		final GridBagConstraints gbc = SwingUtils.getGBC();
		gbc.gridx	= 0;
		gbc.gridy	= 0;
		
		for (final Entry<String, FieldType> entry
				: getType().getFieldsTemplate().entrySet()) {
			final String name = entry.getKey();
			gbc.gridx	= 0;
			add(new InfoLabel(name), gbc);
			
			final TextInput input = new TextInput();
			fields.put(name, input);
			gbc.gridx	= 1;
			add(input, gbc);
			
			gbc.gridy++;
		}
	}
	
	
	
	public TaskType getType() { return type; }
	
	public SortedMap<String, Field> read() throws NumberFormatException {
		final SortedMap<String, Field> fields = new TreeMap<String, Field>();
		
		for (final Entry<String, TextInput> input : this.fields.entrySet()) {
			final String	text	= input.getValue().read();
			if ((text == null) || text.isEmpty())
				throw new IllegalArgumentException("Invalid input (Task fields)");
			
			final String	name	= input.getKey();
			final FieldType	type	=
				getType().getFieldsTemplate().get(name);
			
			final Object	value;
			switch (type) {
				case NUMERICAL:
					value = Integer.parseInt(input.getValue().read());
					break;
					
				case TEXTUAL:
				default:
					value = input.getValue().read();
			}
			
			try {
				fields.put(name, new Field(type, value));
			} catch (final TaskManagerException e) {
				//	should never be reached
				assert false : e;
				throw new InternalError();
			}
		}
		
		return fields;
	}
	
	private final void setType(final TaskType type) {
		if (type == null)
			throw new NullPointerException("TaskType == NULL");
		
		this.type = type;
	}
	
}